import xlwt
import logging
import defaults
from collections import OrderedDict


logger = logging.getLogger('root')


class BaseXLSManager(object):

    def __init__(self, location):
        logger.info('New workbook: {}'.format(location))
        self.book = xlwt.Workbook(encoding='utf-8')
        self.linkStyle = xlwt.easyxf('pattern: pattern solid, fore_colour ice_blue')
        self.headerStyle = xlwt.easyxf('pattern: pattern solid, fore_colour gray25')
        self.location = location
        self.homeSheet = 'Contents'
        self.sheetDict = OrderedDict()
        self.add_contents()

    def add_contents(self):
        self.sheetDict[self.homeSheet] = self.book.add_sheet(self.homeSheet)

    def add_sheet(self, sheetName):
        logger.info('Adding {}.'.format(sheetName))
        self.sheetDict[sheetName] = self.book.add_sheet(sheetName)
        self.add_link(sheetName, 0, 0, self.homeSheet, "<-----")

    def write_to_sheet(self, sheet, data, start=0):
        sheet = self.sheetDict[sheet]
        if not data:
            logger.warning('No data for worksheet.')
            sheet.write(2, 0, 'No Records')
            return
        for rowIndex, rowContents in enumerate(data):
            for colIndex, cellValue in enumerate(rowContents):
                sheet.write(rowIndex + 2, colIndex, cellValue)

    def add_link(self, sheet, row, col, name, text):
        link = 'HYPERLINK("#\'{}\'!A1", "{}")'.format(name, text)
        self.sheetDict[sheet].write(row, col, xlwt.Formula(link), self.linkStyle)

    def external_link(self, sheet, row, col, name, text):
        toLink = name + '.xls'
        link = 'HYPERLINK("[{}]#\'Contents\'!A1", "{}")'.format(toLink, text)
        self.sheetDict[sheet].write(row, col, xlwt.Formula(link), self.linkStyle)

    def write_contents(self):
        contentsRow = 0
        for name in self.sheetDict.keys()[1:]:
            self.add_link(self.homeSheet, contentsRow, 0, name, name)
            contentsRow += 1

    def finalize_book(self):
        logger.info('Creating table of contents.')
        self.write_contents()
        logger.info('Writing to file.')
        try:
            self.book.save(self.location)
        except Exception as e:
            logger.error('Could not write to file: {}'.format(e))


class HostWorkbook(BaseXLSManager):

    def add_host_data(self, hostDict):
        for name, data in hostDict.items():
            self.add_sheet(name)
            self.write_to_sheet(name, data)
        

class SummaryWorkbook(BaseXLSManager):

    def __init__(self, location):
        super(SummaryWorkbook, self).__init__(location)
        self.add_summary()

    def add_summary(self):
        self.sheetDict['Summary'] = self.book.add_sheet('Summary')

    def build_summary(self, data):
        sheet = []
        summary = [['Summary'],
                   ['Host', 'Manufacturer', 'Model', 'Serial #', 'CPU',
                    'Cores', 'Memory', 'User', 'OS', 'Architecture',
                    'Service Pack', 'Install Date', 'Running Processes']]
        disk = [['Disk Alert'],
                ['Host', 'Drive', '% Free']]
        events = [['Events'],
                  ['Host', 'Count']]
        printers = [['Printers'],
                    ['Host', 'Printer', 'Status', 'Error State', 'Extended State']]
        for value in data.values():
            summary.extend(value['summary'])
            if value['disk']:
                disk.extend(value['disk'])
            if value['printers']:
                printers.extend(value['printers'])
            if value['events']:
                events.extend(value['events'])
        sheet.extend(summary)
        if len(disk) > 2:
            sheet.extend(defaults.OUTPUT_SPACES)
            sheet.extend(disk)
        if len(printers) > 2:
            sheet.extend(defaults.OUTPUT_SPACES)
            sheet.extend(printers)
        if len(events) > 2:
            sheet.extend(defaults.OUTPUT_SPACES)
            sheet.extend(events)
        return sheet

    def write_to_summary(self, data):
        doLinks = False
        for rowIndex, rowContents in enumerate(data):
            for colIndex, cellValue in enumerate(rowContents):
                if colIndex == 0:
                    if not cellValue:
                        doLinks = False
                        continue
                    elif doLinks is True:
                        self.external_link('Summary', rowIndex, colIndex, cellValue, cellValue)
                        continue
                    elif cellValue == 'Host':
                        doLinks = True
                self.sheetDict['Summary'].write(rowIndex, colIndex, cellValue)